#include "sim800l.h"

#define sim_delay_ms delay_ms
#define sim_send_data Uart0_SendStr
// #define sim_log_print printf

#define RX_BUFFER_SIZE 328                  // 数组缓存大小
uint8_t SIM_RxBuffer[RX_BUFFER_SIZE] = {0}; // 接收缓存数组
uint16_t SIM_RxDataCnt = 0;                 // 数组下标

#define PHONE_NUMBER "16675205921"
#define SIM_DIAL_COMMAND "ATD" PHONE_NUMBER ";\r\n"
#define SIM_MESSAGE_CONFIG "AT+CMGS=\"+86" PHONE_NUMBER "\"\r\n"


char message_buffer[128] = "Warrning! There may be a person who falls\r\n";
SIM_TypeDef SIMStatus = {0, 0};

uint8_t SIM_get_receive_flag(void)
{
    uint8_t flag = SIMStatus.receiveDataFlag;
    SIMStatus.receiveDataFlag = 0;
    return flag;
}

uint8_t sim800l_send_command(char *cmd, char *res, uint8_t sendCount, uint16_t delay_xms, uint8_t printf_enable)
{
    if (printf_enable == SIM_ENABLE)
        // sim_log_print("%s", cmd); // 这里可以打印每次发送的指令
        while (sendCount--)
        {
            sim_send_data(cmd);                   // AT指令发送
            sim_delay_ms(delay_xms);              // 适当增加点延迟，等待串口接收完成
            if (SIM_get_receive_flag() == SIM_OK) // 如果串口接收到换行回车为结尾的数据
            {
                if (strstr((const char *)SIM_RxBuffer, res) != NULL) // 若找到关键字
                {
                    // sim_log_print("%s", res); // 这里可以打印每次发送的指令
                    sim_clear_buffer(); // 清除数组
                    return 1;           // 退出，返回0-成功
                }
                // sim_log_print("error recovery data:%s", SIM_RxBuffer); // 当接收错误时，打印出接收的数据，方便调试
                sim_clear_buffer();
            }
            sim_delay_ms(500);
        }
    return 0; // 返回1-失败
}
/**
 * @brief SIM卡信号强度检测
 * @回应示例 at+csq
            +CSQ: 12,99
            OK
 */
uint8_t SIM_sign_check(void)
{
    uint8_t cnt = 3;
    int sign1 = 0, sign2 = 0;

    while (cnt--)
    {
        sim_send_data("AT+CSQ\r\n");
        sim_delay_ms(50);
        if (SIM_get_receive_flag() == SIM_OK) // 如果串口接收到换行回车为结尾的数据
        {
            if (strstr((const char *)SIM_RxBuffer, "+CSQ") != NULL)
            {
                const char *res_buffer = strstr((const char *)SIM_RxBuffer, "+CSQ:");
                if (sscanf(res_buffer, "+CSQ: %d,%d\r\n\r\nOK\r\n", &sign1, &sign2) == 2) // 若找到关键字
                {
                    sim_clear_buffer(); // 清除数组 sign1 9
                    if (sign1 > 0 || sign2 > 0)
                        return 1; // 有信号
                    else
                        cnt++;
                }
            }
        }
        sim_delay_ms(500);
    }
    return 0; // 无信号
}
void sim800l_init(void)
{
    // sim_log_print("Start SIM service\r\n");
    if (sim800l_send_command("AT\r\n", "OK", 3, 50, SIM_ENABLE) != SIM_OK)
    {
        // sim_log_print("AT error\r\n");
        SIMStatus.error_code |= (1 << 0);
    }
    if (sim800l_send_command("AT+cpin?\r\n", "OK", 3, 50, SIM_ENABLE) != SIM_OK)
    {
        // sim_log_print("No SIMCard\r\n");
        SIMStatus.error_code |= (1 << 1);
    }
    if (SIM_sign_check() == 0)
    {
        // sim_log_print("SIMCard No Signal\r\n");
        SIMStatus.error_code |= (1 << 2);
    }
}
void sim800l_send_message(void)
{
    if (sim800l_send_command("AT+CMGF=1\r\n", "OK", 3, 50, SIM_ENABLE) != SIM_OK)
    {
        // sim_log_print("AT+CMGF=1 Error\r\n");
        SIMStatus.error_code |= (1 << 3);
    }
    // 准备发送短信
    if (SIMStatus.error_code == 0x00)
    {
        if (sim800l_send_command(SIM_MESSAGE_CONFIG, ">", 3, 1000, SIM_ENABLE) == SIM_OK)
        {
            // 3. 发送短信内容 + 0x1A
            sim_send_data(message_buffer); // 发送文本
            sim_send_data("\x1A");         // 发送Ctrl+Z（0x1A）结束
            // sim_log_print("%s Message sent!\r\n", message_buffer);
        }
        else
        {
            // sim_log_print("Failed to start SMS.\r\n");
        }
    }
}
uint8_t sim800l_dial_attempt(void)
{
    sim_send_data(SIM_DIAL_COMMAND);      // AT指令发送拨号命令
    sim_delay_ms(5000);                    // 适当增加点延迟，等待串口接收完成
    if (SIM_get_receive_flag() == SIM_OK) // 如果串口接收到换行回车为结尾的数据
    {
        if (strstr((const char *)SIM_RxBuffer, "OK") != NULL) // 拨号成功
        {
            // sim_log_print("Dial successfully\r\n");
            sim_clear_buffer(); // 清除数组
            return SIM_OK;      // 退出，返回0-成功
        }
    }
    //sim_delay_ms(1000);
    return 0;
}

void sim800l_dial(void)
{
    sim800l_dial_attempt();
		sim800l_send_message();
}
void sim_clear_buffer(void)
{
    memset(SIM_RxBuffer, 0, sizeof(SIM_RxBuffer));
    SIM_RxDataCnt = 0;
}
void sim800l_receive_callback(uint8_t byte)
{
    SIM_RxBuffer[SIM_RxDataCnt++] = byte; // 接收数据转存
    if (SIM_RxDataCnt > RX_BUFFER_SIZE)   // 判断接收数据是否溢出
    {
        sim_clear_buffer();
    }
    if (SIM_RxDataCnt >= 2 && (SIM_RxBuffer[SIM_RxDataCnt - 2] == '\r' && SIM_RxBuffer[SIM_RxDataCnt - 1] == '\n')) // 判断结束位
    {
        SIMStatus.receiveDataFlag = 1;  
    }
}
